package com.leador.map.api.location.core;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.location.Address;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.os.Looper;
import android.text.Html;
import android.text.Spanned;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import com.leador.map.api.location.MapLocation;

/**
 * CoreUtil
 * <p/>
 * <p/>
 * Base class with code to manage the tool methods
 *
 * @author
 * @version 1.0 2010.01.22<br>
 */
public class CoreUtil {
    // public static final String LICENSE =
    // "E4352BBB36374B8A4013ED90477495F8";
    public static final String LICENSE = "32M0145A3D7E1266UY6BC6E017AD2387";
    public static final String EmptyString = "";
    private static final long NanaSeconds = 1000000000;
    public static final int E6Multiple = 1000000;
    private static String SMD5 = null;

    public static final String HtmlBlack = "#000000";
    public static final String HtmlGray = "#808080";
    public static final String HtmlStrong = "strong";
    // private static String apiKey;
    public static boolean is900913 = true;

    public static boolean IsEmptyOrNullString(String s) {
        return (s == null) || (s.trim().length() == 0);
    }

    public static long getCurrentTimeStamp() {
        long stamp = System.nanoTime() / NanaSeconds;
        return stamp;
    }

    public static long getCurrentTimeStampInMilly() {
        long stamp = System.nanoTime() * 1000 / NanaSeconds;
        return stamp;
    }

    public static int E6ToMeter(int e6Span) {
        // 111.7 KM
        return (int) (1117 * ((long) e6Span) / (E6Multiple / 100));
    }

    public static int MeterToE6(int meter) {
        return (int) ((long) meter * E6Multiple / (1117 * 100));
    }

    public static boolean isOverdue(long stamp, long cur,
                                    long over_bar_in_seconds) {
        return cur - stamp > over_bar_in_seconds;
    }

    public static Document getXml(InputStream in) {
        Document xml = null;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            xml = builder.parse(in);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return xml;
    }

    public static Document getXml(String xml) {
        return getXml(new ByteArrayInputStream(xml.getBytes()));
    }

    public static Looper makeLooper() {
        if (Looper.myLooper() == null) {
            Looper.prepare();
            Looper.loop();
        }

        return Looper.myLooper();
    }

    public static String loadMd5(Context activity) {
        if (SMD5 == null) {
            final char[] Sigs = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
                    '9', 'A', 'B', 'C', 'D', 'E', 'F'};
            String Md5 = EmptyString;
            try {
                Signature[] sigs = activity.getPackageManager().getPackageInfo(
                        activity.getPackageName(),
                        PackageManager.GET_SIGNATURES).signatures;
                MessageDigest md5 = MessageDigest.getInstance("MD5");
                md5.update(sigs[0].toByteArray());
                byte[] digest = md5.digest();
                for (int di = 0; di < digest.length; di++) {
                    int tmp = digest[di] < 0 ? 256 + digest[di] : digest[di];
                    Md5 += Sigs[tmp / 16];
                    Md5 += Sigs[tmp % 16];
                    if (di != digest.length - 1) {
                        Md5 += ":";
                    }
                }
                SMD5 = Md5;
            } catch (NoSuchAlgorithmException e) {
            } catch (NameNotFoundException e) {
            }
        }

        return SMD5;
    }

    public static Proxy getProxy(Context cnt) {
        Proxy proxy = null;
        try {
            ConnectivityManager connMgr = (ConnectivityManager) cnt
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo info = connMgr.getActiveNetworkInfo();
            if (null != info) {
                String proxyHost = null;
                int proxyPort = 0;
                if (info.getType() == ConnectivityManager.TYPE_WIFI) {
                    // WIFI: global http proxy
                    proxyHost = android.net.Proxy.getHost(cnt);
                    proxyPort = android.net.Proxy.getPort(cnt);
                } else {
                    // GPRS: APN http proxy
                    proxyHost = android.net.Proxy.getDefaultHost();
                    proxyPort = android.net.Proxy.getDefaultPort();
                }

                if (proxyHost != null) {
                    proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP,
                            new InetSocketAddress(proxyHost, proxyPort));
                }
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return proxy;
    }

    public static long LatLonToE6(double pos) {

        return (long) (pos * E6Multiple);
    }

    public static double E6ToLatLon(long e6) {

        return ((double) e6) / E6Multiple;
    }

    public static boolean isNear(Rect rect, int enlargeDis, Point pt) {
        Rect rc = new Rect(rect.left - enlargeDis, rect.top - enlargeDis,
                rect.right + enlargeDis, rect.bottom + enlargeDis);

        return rc.contains(pt.x, pt.y);
    }

    public static void Log(String tag, String msg) {
        Log.e(tag, msg);
    }

    public static Address makeDefaultAddress() {
        Address addr = new Address(Locale.CHINA);
        addr.setCountryCode("CN");
        addr.setCountryName("\u4e2d\u56fd");// 中国 \u4e2d\u56fd

        return addr;
    }

    public static String addTag(String src, String tag) {
        String result = src;

        StringBuilder buf = new StringBuilder();
        buf.append("<").append(tag).append(">");
        buf.append(src);
        buf.append("</").append(tag).append(">");
        result = buf.toString();

        return result;
    }

    public static String makeHtmlSpace(int number) {
        final String space = "&nbsp;";
        // String result = "";
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < number; i++) {
            // result += Space;
            result.append(space);
        }
        return result.toString();
    }

    static float[] ScalesBuf = new float[9];

    public static float getMatrixValue(Matrix mx, int index) {

        mx.getValues(ScalesBuf);
        return ScalesBuf[index];
    }

    public static String makeHtmlNewLine() {
        return "<br />";
    }

    public static Spanned stringToSpan(String src) {
        return src == null ? null : Html.fromHtml(src.replace("\n", "<br />"));
    }

    public static String colorFont(String src, String color) {
        StringBuffer strBuf = new StringBuffer();

        strBuf.append("<font color=").append(color).append(">").append(src)
                .append("</font>");
        return strBuf.toString();
    }

    // dip转换成px
    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    // px转换成dip
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    // 检测网络环境
    public static boolean isNetworkOK(Context context) {
        if (context == null) {
            return false;
        }
        ConnectivityManager conn = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (conn == null) {
            return false;
        }
        NetworkInfo netInfo = conn.getActiveNetworkInfo();
        if (netInfo == null) {
            return false;
        }
        State stateNet = netInfo.getState();
        if (stateNet == null || stateNet == NetworkInfo.State.DISCONNECTED
                || stateNet == NetworkInfo.State.DISCONNECTING) {
            return false;
        }
        return true;
    }

    public static final String LAST_KNOW_LOCATION = "last_know_location";
    public static final String LAST_KNOW_LAT = "last_know_lat"; // 上次的纬度
    public static final String LAST_KNOW_LNG = "last_know_lng"; // 上次的经度


    /**
     * 得到存储的 上次定位位置
     *
     * @param context
     * @return
     */
    public static MapLocation getPrefsLocation(Context context) {
        SharedPreferences prefs = context.getSharedPreferences(
                LAST_KNOW_LOCATION, Context.MODE_PRIVATE);
        String str = "";
        //
        MapLocation location = new MapLocation(str);
        location.setProvider("lbs");
        double lat = Double.parseDouble(prefs.getString(LAST_KNOW_LAT, "0.0"));
        double lng = Double.parseDouble(prefs.getString(LAST_KNOW_LNG, "0.0"));
        location.setLatitude(lat);
        location.setLongitude(lng);
        return location;
    }

    // 存储上次定位的信息
    public static void setPrefsLocation(Context context, MapLocation lastLocation) {
        SharedPreferences prefs = context.getSharedPreferences(
                LAST_KNOW_LOCATION, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(LAST_KNOW_LAT,
                String.valueOf(lastLocation.getLatitude()));
        editor.putString(LAST_KNOW_LNG,
                String.valueOf(lastLocation.getLongitude()));
        editor.commit();
    }


    public static void paseAuthFailurJson(String str) throws LocationException {
        try {
            JSONObject jObj = new JSONObject(str);
            if (jObj.has("status")) {
                String statusDes = jObj.getString("status");
                if (statusDes.equals("E6008")) {
                    throw new LocationException("key为空");
                }
                if (statusDes.equals("E6012")) {
                    throw new LocationException("key不存在");
                }
                if (statusDes.equals("E6018")) {
                    throw new LocationException("key被锁定");
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}
